home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / Windows / WMESA.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-26  |  83.0 KB  |  2,885 lines

  1. /* $Id: wmesa.c,v 3.1 1998/06/11 01:42:08 brianp Exp $ */
  2.  
  3. /*
  4. *   File name   :   wmesa.c
  5. *  Version      :   2.3
  6. *
  7. *  Display driver for Mesa 2.3  under
  8. *   Windows95 and WindowsNT
  9. *
  10. *   Copyright (C) 1996-  Li Wei
  11. *  Address      :       Institute of Artificial Intelligence
  12. *               :           & Robotics
  13. *               :       Xi'an Jiaotong University
  14. *  Email        :       liwei@aiar.xjtu.edu.cn
  15. *  Web page :       http://sun.aiar.xjtu.edu.cn
  16. *
  17. *  This file and its associations are partially borrowed from the
  18. *  Windows NT driver for Mesa 1.8 , written by Mark Leaming
  19. *  (mark@rsinc.com).
  20. */
  21.  
  22.  
  23. /*
  24.  * $Log: wmesa.c,v $
  25.  * Revision 3.1  1998/06/11 01:42:08  brianp
  26.  * updated for Mesa 3.0 device driver interface (but not tested)
  27.  *
  28.  * Revision 3.0  1998/06/11 01:18:25  brianp
  29.  * initial revision
  30.  *
  31.  */
  32.  
  33.  
  34. #define WMESA_STEREO_C
  35.  
  36. #include <windows.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <GL/wmesa.h>
  40. #include "mesa_extend.h"
  41. #include "colors.h"
  42. #include "macros.h"
  43. #include "context.h"
  44. #include "dd.h"
  45. #include "xform.h"
  46. #include "vb.h"
  47. #include "matrix.h"
  48. #include "depth.h"
  49. #include "wmesadef.h"
  50.  
  51. #pragma warning ( disable : 4133 4761 )
  52.  
  53. #ifdef PROFILE
  54. //  #include "profile.h"
  55. #endif
  56.  
  57. #ifdef DITHER
  58. #include <wing.h>
  59. #endif
  60.  
  61. #ifdef __CYGWIN32__
  62. #include "macros.h"
  63. #include <string.h>
  64. #define CopyMemory memcpy
  65. #endif
  66.  
  67. #if !defined(NO_STEREO)
  68.  
  69. #include "gl\glu.h"
  70. #include "stereo.h"
  71.  
  72. #endif
  73. #if !defined(NO_PARALLEL)
  74. //  #include "parallel.h"
  75. #endif
  76.  
  77. struct DISPLAY_OPTIONS displayOptions;
  78.  
  79. GLenum stereoCompile = GL_FALSE ;
  80. GLenum stereoShowing  = GL_FALSE ;
  81. GLenum stereoBuffer = GL_FALSE;
  82. #if !defined(NO_STEREO)
  83. GLint displayList = MAXIMUM_DISPLAY_LIST ;
  84. #endif
  85. GLint stereo_flag = 0 ;
  86.  
  87. /* end of added code*/
  88.  
  89. static PWMC Current = NULL;
  90. WMesaContext WC = NULL;
  91.  
  92. #ifdef NDEBUG
  93. #define assert(ignore)  ((void) 0)
  94. #else
  95. void Mesa_Assert(void *Cond,void *File,unsigned Line)
  96. {
  97.     char Msg[512];
  98.     sprintf(Msg,"%s %s %d",Cond,File,Line);
  99.     MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
  100.     exit(1);
  101. }
  102. #define assert(e)   if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
  103. #endif
  104.  
  105. //#define DD_GETDC (Current->hDC )
  106. #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
  107. //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
  108. #define DD_RELEASEDC
  109.  
  110. //#define BEGINGDICALL  if(Current->rgb_flag)wmFlushBits(Current);
  111. #define BEGINGDICALL
  112. //#define ENDGDICALL        if(Current->rgb_flag)wmGetBits(Current);
  113. #define ENDGDICALL
  114.  
  115. //#define FLIP(Y)  (Current->dither_flag? Y : Current->height-(Y)-1)
  116. //#define FLIP(Y)  (Current->height-(Y)-1)
  117. //#define FLIP(Y) Y
  118. #define FLIP(Y)  (Current->db_flag? Y: Current->height-(Y)-1)
  119. #define STARTPROFILE
  120. #define ENDPROFILE(PARA)
  121.  
  122. #define DITHER_RGB_TO_8BIT_SETUP            \
  123. GLubyte pixelDithered;
  124.  
  125. #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline)               \
  126. {                                                                           \
  127.     char unsigned redtemp, greentemp, bluetemp, paletteindex;               \
  128.     redtemp = aDividedBy51[red]                                             \
  129.     + (aModulo51[red] > aHalftone8x8[(pixel%8)*8                        \
  130.     + scanline%8]);                                                 \
  131.     greentemp = aDividedBy51[(char unsigned)green]                          \
  132.     + (aModulo51[green] > aHalftone8x8[                             \
  133.     (pixel%8)*8 + scanline%8]);                                     \
  134.     bluetemp = aDividedBy51[(char unsigned)blue]                            \
  135.     + (aModulo51[blue] > aHalftone8x8[                              \
  136.     (pixel%8)*8 +scanline%8]);                                      \
  137.     paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];       \
  138.     pixelDithered = aWinGHalftoneTranslation[paletteindex];                 \
  139. }
  140.  
  141.  
  142. #ifdef DDRAW
  143. static BOOL DDInit( WMesaContext wc, HWND hwnd);
  144. static void DDFree( WMesaContext wc);
  145. static HRESULT DDRestoreAll( WMesaContext wc );
  146. static void DDDeleteOffScreen(WMesaContext wc);
  147. static BOOL DDCreateOffScreen(WMesaContext wc);
  148. #endif
  149.  
  150. static void FlushToFile(PWMC pwc, PSTR  szFile);
  151.  
  152. BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
  153. BOOL wmDeleteBackingStore(PWMC pwc);
  154. void wmCreatePalette( PWMC pwdc );
  155. BOOL wmSetDibColors(PWMC pwc);
  156. void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
  157.  
  158. void wmCreateDIBSection(
  159.                         HDC  hDC,
  160.                         PWMC pwc,   // handle of device context
  161.                         CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
  162.                         UINT iUsage // color data type indicator: RGB values or palette indices
  163.                         );
  164.  
  165.  
  166. void WMesaViewport( GLcontext *ctx,
  167.                     GLint x, GLint y, GLsizei width, GLsizei height );
  168.  
  169.  
  170. static triangle_func choose_triangle_function( GLcontext *ctx );
  171.  
  172.  
  173. static void wmSetPixelFormat( PWMC wc, HDC hDC)
  174. {
  175.     if(wc->rgb_flag)
  176.         wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
  177.     else
  178.         wc->cColorBits = 8;
  179.     switch(wc->cColorBits){
  180.     case 8:
  181.         if(wc->dither_flag != GL_TRUE)
  182.             wc->pixelformat = PF_INDEX8;
  183.         else
  184.             wc->pixelformat = PF_DITHER8;
  185.         break;
  186.     case 16:
  187.         wc->pixelformat = PF_5R6G5B;
  188.         break;
  189.     case 32:
  190.         wc->pixelformat = PF_8R8G8B;
  191.         break;
  192.     default:
  193.         wc->pixelformat = PF_BADFORMAT;
  194.     }
  195. }
  196.  
  197. //
  198. // This function sets the color table of a DIB section
  199. // to match that of the destination DC
  200. //
  201. BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
  202. {
  203.     RGBQUAD         *pColTab, *pRGB;
  204.     PALETTEENTRY    *pPal, *pPE;
  205.     int             i, nColors;
  206.     BOOL            bRet=TRUE;
  207.     DWORD           dwErr=0;
  208.  
  209.     /* Build a color table in the DIB that maps to the
  210.     selected palette in the DC.
  211.     */
  212.     nColors = 1 << pwc->cColorBits;
  213.     pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
  214.     memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
  215.     GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
  216.     pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
  217.     for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
  218.         pRGB->rgbRed = pPE->peRed;
  219.         pRGB->rgbGreen = pPE->peGreen;
  220.         pRGB->rgbBlue = pPE->peBlue;
  221.     }
  222.     if(pwc->db_flag)
  223.         bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
  224.  
  225.     if(!bRet)
  226.         dwErr = GetLastError();
  227.  
  228.     free( pColTab );
  229.     free( pPal );
  230.  
  231.     return(bRet);
  232. }
  233.  
  234.  
  235. //
  236. // Free up the dib section that was created
  237. //
  238. BOOL wmDeleteBackingStore(PWMC pwc)
  239. {
  240.     SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
  241.     DeleteDC(pwc->dib.hDC);
  242.     DeleteObject(pwc->hbmDIB);
  243.     UnmapViewOfFile(pwc->dib.base);
  244.     CloseHandle(pwc->dib.hFileMap);
  245.     return TRUE;
  246. }
  247.  
  248.  
  249. //
  250. // This function creates the DIB section that is used for combined
  251. // GL and GDI calls
  252. //
  253. BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
  254. {
  255.     HDC hdc = pwc->hDC;
  256.     LPBITMAPINFO pbmi = &(pwc->bmi);
  257.     int     iUsage;
  258.  
  259.     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  260.     pbmi->bmiHeader.biWidth = lxSize;
  261.     pbmi->bmiHeader.biHeight= -lySize;
  262.     pbmi->bmiHeader.biPlanes = 1;
  263.     if(pwc->rgb_flag)
  264.         pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
  265.     else
  266.         pbmi->bmiHeader.biBitCount = 8;
  267.     pbmi->bmiHeader.biCompression = BI_RGB;
  268.     pbmi->bmiHeader.biSizeImage = 0;
  269.     pbmi->bmiHeader.biXPelsPerMeter = 0;
  270.     pbmi->bmiHeader.biYPelsPerMeter = 0;
  271.     pbmi->bmiHeader.biClrUsed = 0;
  272.     pbmi->bmiHeader.biClrImportant = 0;
  273.  
  274.     iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
  275.  
  276.     pwc->cColorBits = pbmi->bmiHeader.biBitCount;
  277.     pwc->ScanWidth = pwc->pitch = lxSize;
  278.  
  279.     wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
  280.  
  281.     if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
  282.         wmCreatePalette( pwc );
  283.         wmSetDibColors( pwc );
  284.     }
  285.     wmSetPixelFormat(pwc, pwc->hDC);
  286.     return(TRUE);
  287.  
  288. }
  289.  
  290.  
  291. //
  292. // This function copies one scan line in a DIB section to another
  293. //
  294. BOOL WINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
  295. {
  296.     UINT uiScans = 0;
  297.     LPBYTE  pDest = pwc->pbPixels;
  298.     DWORD   dwNextScan = uiScanWidth;
  299.     DWORD   dwNewScan = uiNewWidth;
  300.     DWORD   dwScanWidth = (uiScanWidth * nBypp);
  301.  
  302.     //
  303.     // We need to round up to the nearest DWORD
  304.     // and multiply by the number of bytes per
  305.     // pixel
  306.     //
  307.     dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
  308.     dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
  309.  
  310.     for(uiScans = 0; uiScans < uiNumScans; uiScans++){
  311.         CopyMemory(pDest, pBits, dwScanWidth);
  312.         pBits += dwNextScan;
  313.         pDest += dwNewScan;
  314.     }
  315.  
  316.     return(TRUE);
  317.  
  318. }
  319.  
  320.  
  321. BOOL wmFlush(PWMC pwc);
  322.  
  323. /*
  324. * Useful macros:
  325. Modified from file osmesa.c
  326. */
  327.  
  328.  
  329. #define PIXELADDR(X,Y)  ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
  330. #define PIXELADDR1( X, Y )  \
  331. ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
  332. #define PIXELADDR2( X, Y )  \
  333. ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
  334. #define PIXELADDR4( X, Y )  \
  335. ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
  336.  
  337.  
  338. BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y);
  339.  
  340. /* Finish all pending operations and synchronize. */
  341. static void finish(GLcontext* ctx)
  342. {
  343.     /* No op */
  344. }
  345.  
  346.  
  347. //
  348. // We cache all gl draw routines until a flush is made
  349. //
  350. static void flush(GLcontext* ctx)
  351. {
  352.     STARTPROFILE
  353.         if((Current->rgb_flag /*&& !(Current->dib.fFlushed)*/&&!(Current->db_flag))
  354.             ||(!Current->rgb_flag))
  355.         {
  356.             wmFlush(Current);
  357.         }
  358.         ENDPROFILE(flush)
  359.  
  360. }
  361.  
  362.  
  363.  
  364. /*
  365. * Set the color index used to clear the color buffer.
  366. */
  367. static void clear_index(GLcontext* ctx, GLuint index)
  368. {
  369.     STARTPROFILE
  370.         Current->clearpixel = index;
  371.     ENDPROFILE(clear_index)
  372. }
  373.  
  374.  
  375.  
  376. /*
  377. * Set the color used to clear the color buffer.
  378. */
  379. static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  380. {
  381.     STARTPROFILE
  382.         Current->clearpixel=RGB(r, g, b );
  383.     ENDPROFILE(clear_color)
  384. }
  385.  
  386.  
  387.  
  388. /*
  389. * Clear the specified region of the color buffer using the clear color
  390. * or index as specified by one of the two functions above.
  391. */
  392. //static void clear(GLcontext* ctx,
  393. //                  GLboolean all,GLint x, GLint y, GLint width, GLint height )
  394. // TODO: I modified this function to match the prototype in dd.h. (swansma@geocities.com)
  395. //       dd.h does not explain what the return type is so I could not set this to the proper
  396. //       value.
  397. static GLbitfield clear(GLcontext* ctx, GLbitfield mask,
  398.                   GLboolean all, GLint x, GLint y, GLint width, GLint height)
  399. {
  400.     DWORD   dwColor;
  401.     WORD    wColor;
  402.     BYTE    bColor;
  403.     LPDWORD lpdw = (LPDWORD)Current->pbPixels;
  404.     LPWORD  lpw = (LPWORD)Current->pbPixels;
  405.     LPBYTE  lpb = Current->pbPixels;
  406.     int     lines;
  407.  
  408.     STARTPROFILE
  409.  
  410.         if (all){
  411.             x=y=0;
  412.             width=Current->width;
  413.             height=Current->height;
  414.         }
  415.         if(Current->db_flag==GL_TRUE){
  416.             UINT    nBypp = Current->cColorBits / 8;
  417.             int     i = 0;
  418.             int     iSize = 0;
  419.  
  420.             if(nBypp ==1 ){
  421.                 /* Need rectification */
  422.                 iSize = Current->width/4;
  423.                 bColor  = BGR8(GetRValue(Current->clearpixel),
  424.                     GetGValue(Current->clearpixel),
  425.                     GetBValue(Current->clearpixel));
  426.                 wColor  = MAKEWORD(bColor,bColor);
  427.                 dwColor = MAKELONG(wColor, wColor);
  428.             }
  429.             if(nBypp == 2){
  430.                 iSize = Current->width / 2;
  431.                 wColor = BGR16(GetRValue(Current->clearpixel),
  432.                     GetGValue(Current->clearpixel),
  433.                     GetBValue(Current->clearpixel));
  434.                 dwColor = MAKELONG(wColor, wColor);
  435.             }
  436.             else if(nBypp == 4){
  437.                 iSize = Current->width;
  438.                 dwColor = BGR32(GetRValue(Current->clearpixel),
  439.                     GetGValue(Current->clearpixel),
  440.                     GetBValue(Current->clearpixel));
  441.             }
  442.  
  443.             while(i < iSize){
  444.                 *lpdw = dwColor;
  445.                 lpdw++;
  446.                 i++;
  447.             }
  448.  
  449.             //
  450.             // This is the 24bit case
  451.             //
  452.             if (nBypp == 3) {
  453.                 iSize = Current->width *3/4;
  454.                 dwColor = BGR24(GetRValue(Current->clearpixel),
  455.                     GetGValue(Current->clearpixel),
  456.                     GetBValue(Current->clearpixel));
  457.                 while(i < iSize){
  458.                     *lpdw = dwColor;
  459.                     lpb += nBypp;
  460.                     lpdw = (LPDWORD)lpb;
  461.                     i++;
  462.                 }
  463.             }
  464.  
  465.             i = 0;
  466.             if (stereo_flag)
  467.                lines = height /2;
  468.             else
  469.                lines = height;
  470.             do {
  471.                 memcpy(lpb, Current->pbPixels, iSize*4);
  472.                 lpb += Current->ScanWidth;
  473.                 i++;
  474.             }
  475.             while (i<lines-1);
  476.         }
  477.         else { // For single buffer
  478.             HDC DC=DD_GETDC;
  479.             HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
  480.             HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
  481.             HPEN Old_Pen=SelectObject(DC,Pen);
  482.             HBRUSH Old_Brush=SelectObject(DC,Brush);
  483.             Rectangle(DC,x,y,x+width,y+height);
  484.             SelectObject(DC,Old_Pen);
  485.             SelectObject(DC,Old_Brush);
  486.             DeleteObject(Pen);
  487.             DeleteObject(Brush);
  488.             DD_RELEASEDC;
  489.         }
  490.  
  491.  
  492.  
  493.         ENDPROFILE(clear)
  494.  
  495.         return mask;    // TODO: I doubt this is correct. dd.h doesn't explain what this should
  496.                         //       be...
  497. }
  498.  
  499.  
  500.  
  501. /* Set the current color index. */
  502. static void set_index(GLcontext* ctx, GLuint index)
  503. {
  504.     STARTPROFILE
  505.         Current->pixel=index;
  506.     ENDPROFILE(set_index)
  507. }
  508.  
  509.  
  510.  
  511. /* Set the current RGBA color. */
  512. static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  513. {
  514.     STARTPROFILE
  515.         Current->pixel = RGB( r, g, b );
  516.     ENDPROFILE(set_color)
  517. }
  518.  
  519.  
  520.  
  521. /* Set the index mode bitplane mask. */
  522. static GLboolean index_mask(GLcontext* ctx, GLuint mask)
  523. {
  524.     /* can't implement */
  525.     return GL_FALSE;
  526. }
  527.  
  528.  
  529.  
  530. /* Set the RGBA drawing mask. */
  531. static GLboolean color_mask( GLcontext* ctx,
  532.                             GLboolean rmask, GLboolean gmask,
  533.                             GLboolean bmask, GLboolean amask)
  534. {
  535.     /* can't implement */
  536.     return GL_FALSE;
  537. }
  538.  
  539.  
  540.  
  541. /*
  542. * Set the pixel logic operation.  Return GL_TRUE if the device driver
  543. * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
  544. * is returned, the logic op will be done in software by Mesa.
  545. */
  546. GLboolean logicop( GLcontext* ctx, GLenum op )
  547. {
  548.     /* can't implement */
  549.     return GL_FALSE;
  550. }
  551.  
  552.  
  553. static void dither( GLcontext* ctx, GLboolean enable )
  554. {
  555.     if(enable == GL_FALSE){
  556.         Current->dither_flag = GL_FALSE;
  557.         if(Current->cColorBits == 8)
  558.             Current->pixelformat = PF_INDEX8;
  559.     }
  560.     else{
  561.         if (Current->rgb_flag && Current->cColorBits == 8){
  562.             Current->pixelformat = PF_DITHER8;
  563.             Current->dither_flag = GL_TRUE;
  564.         }
  565.         else
  566.             Current->dither_flag = GL_FALSE;
  567.     }
  568. }
  569.  
  570.  
  571.  
  572. static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
  573. {
  574.    STARTPROFILE
  575.    /* TODO: this could be better */
  576.    if (mode==GL_FRONT || mode==GL_BACK) {
  577.       return GL_TRUE;
  578.    }
  579.    else {
  580.       return GL_FALSE;
  581.    }
  582.    ENDPROFILE(set_buffer)
  583. }
  584.  
  585.  
  586.  
  587. /* Return characteristics of the output buffer. */
  588. static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height )
  589. {
  590.    int New_Size;
  591.    RECT CR;
  592.  
  593.    STARTPROFILE
  594.    GetClientRect(Current->Window,&CR);
  595.  
  596.    *width=CR.right;
  597.    *height=CR.bottom;
  598.  
  599.    New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
  600.  
  601.    if (New_Size){
  602.       Current->width=*width;
  603.       Current->height=*height;
  604.       Current->ScanWidth=Current->width;
  605.       if ((Current->ScanWidth%sizeof(long))!=0)
  606.          Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
  607.  
  608.       if (Current->db_flag){
  609. #ifdef DDRAW
  610.          DDDeleteOffScreen(Current);
  611.          DDCreateOffScreen(Current);
  612. #else
  613.          if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
  614.             wmDeleteBackingStore(Current);
  615.             wmCreateBackingStore(Current, Current->width, Current->height);
  616.          }
  617. #endif
  618.       }
  619.  
  620.       //  Resize OsmesaBuffer if in Parallel mode
  621. #if !defined(NO_PARALLEL)
  622.       if(parallelFlag)
  623.          PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
  624.                             Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
  625. #endif
  626.    }
  627.    ENDPROFILE(buffer_size)
  628. }
  629.  
  630.  
  631.  
  632. /**********************************************************************/
  633. /*****           Accelerated point, line, polygon rendering       *****/
  634. /**********************************************************************/
  635.  
  636.  
  637. static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
  638. {
  639.     GLuint i;
  640.     //  HDC DC=DD_GETDC;
  641.     PWMC    pwc = Current;
  642.  
  643.     STARTPROFILE
  644.  
  645.         if (Current->gl_ctx->VB->MonoColor) {
  646.             /* all drawn with current color */
  647.             for (i=first;i<=last;i++) {
  648.                 if (!Current->gl_ctx->VB->ClipMask[i]) {
  649.                     int x, y;
  650.                     x =       (GLint) Current->gl_ctx->VB->Win[i][0];
  651.                     y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
  652.                     wmSetPixel(pwc, y,x,GetRValue(Current->pixel),
  653.                         GetGValue(Current->pixel), GetBValue(Current->pixel));
  654.                 }
  655.             }
  656.         }
  657.         else {
  658.             /* draw points of different colors */
  659.             for (i=first;i<=last;i++) {
  660.                 if (!Current->gl_ctx->VB->ClipMask[i]) {
  661.                     int x, y;
  662.                     unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,
  663.                         Current->gl_ctx->VB->Color[i][1]*255.0,
  664.                         Current->gl_ctx->VB->Color[i][2]*255.0);
  665.                     x =       (GLint) Current->gl_ctx->VB->Win[i][0];
  666.                     y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
  667.                     wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0,
  668.                         Current->gl_ctx->VB->Color[i][1]*255.0,
  669.                         Current->gl_ctx->VB->Color[i][2]*255.0);
  670.                 }
  671.             }
  672.         }
  673.         //   DD_RELEASEDC;
  674.         ENDPROFILE(fast_rgb_points)
  675. }
  676.  
  677.  
  678.  
  679. /* Return pointer to accerated points function */
  680. extern points_func choose_points_function( GLcontext* ctx )
  681. {
  682.     STARTPROFILE
  683.         if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0
  684.             && !ctx->Texture.Enabled  && ctx->Visual->RGBAflag) {
  685.             ENDPROFILE(choose_points_function)
  686.                 return fast_rgb_points;
  687.         }
  688.         else {
  689.             ENDPROFILE(choose_points_function)
  690.                 return NULL;
  691.         }
  692. }
  693.  
  694.  
  695.  
  696. /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
  697. static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
  698. {
  699.     STARTPROFILE
  700.         int x0, y0, x1, y1;
  701.     unsigned long pixel;
  702.     HDC DC=DD_GETDC;
  703.     HPEN Pen;
  704.     HPEN Old_Pen;
  705.  
  706.     if (Current->gl_ctx->VB->MonoColor) {
  707.         pixel = Current->pixel;  /* use current color */
  708.     }
  709.     else {
  710.         pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
  711.     }
  712.  
  713.     x0 =       (int) Current->gl_ctx->VB->Win[v0][0];
  714.     y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );
  715.     x1 =       (int) Current->gl_ctx->VB->Win[v1][0];
  716.     y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );
  717.  
  718.  
  719.     BEGINGDICALL
  720.  
  721.     Pen=CreatePen(PS_SOLID,1,pixel);
  722.     Old_Pen=SelectObject(DC,Pen);
  723.     MoveToEx(DC,x0,y0,NULL);
  724.     LineTo(DC,x1,y1);
  725.     SelectObject(DC,Old_Pen);
  726.     DeleteObject(Pen);
  727.     DD_RELEASEDC;
  728.  
  729.     ENDGDICALL
  730.  
  731.     ENDPROFILE(fast_flat_rgb_line)
  732. }
  733.  
  734.  
  735.  
  736. /* Return pointer to accerated line function */
  737. static line_func choose_line_function( GLcontext* ctx )
  738. {
  739.     STARTPROFILE
  740.     if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
  741.         && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
  742.         && !ctx->Texture.Enabled && Current->rgb_flag) {
  743.        ENDPROFILE(choose_line_function)
  744.        return fast_flat_rgb_line;
  745.     }
  746.     else {
  747.        ENDPROFILE(choose_line_function)
  748.        return NULL;
  749.     }
  750. }
  751.  
  752.  
  753. /**********************************************************************/
  754. /*****                 Span-based pixel drawing                   *****/
  755. /**********************************************************************/
  756.  
  757.  
  758. /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
  759. static void write_ci32_span( const GLcontext* ctx,
  760.                              GLuint n, GLint x, GLint y,
  761.                              const GLuint index[],
  762.                              const GLubyte mask[] )
  763. {
  764.     STARTPROFILE
  765.     GLuint i;
  766.     PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
  767.     assert(Current->rgb_flag==GL_FALSE);
  768.     for (i=0; i<n; i++)
  769.         if (mask[i])
  770.             Mem[i]=index[i];
  771.     ENDPROFILE(write_ci32_span)
  772. }
  773.  
  774.  
  775. /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
  776. static void write_ci8_span( const GLcontext* ctx,
  777.                             GLuint n, GLint x, GLint y,
  778.                             const GLubyte index[],
  779.                             const GLubyte mask[] )
  780. {
  781.     STARTPROFILE
  782.     GLuint i;
  783.     PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
  784.     assert(Current->rgb_flag==GL_FALSE);
  785.     for (i=0; i<n; i++)
  786.         if (mask[i])
  787.             Mem[i]=index[i];
  788.     ENDPROFILE(write_ci8_span)
  789. }
  790.  
  791.  
  792.  
  793. /*
  794. * Write a horizontal span of pixels with a boolean mask.  The current
  795. * color index is used for all pixels.
  796. */
  797. static void write_mono_ci_span(const GLcontext* ctx,
  798.                                GLuint n,GLint x,GLint y,
  799.                                const GLubyte mask[])
  800. {
  801.    STARTPROFILE
  802.    GLuint i;
  803.    BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
  804.    assert(Current->rgb_flag==GL_FALSE);
  805.    for (i=0; i<n; i++)
  806.       if (mask[i])
  807.          Mem[i]=Current->pixel;
  808.    ENDPROFILE(write_mono_ci_span)
  809. }
  810.  
  811. /*
  812.  * To improve the performance of this routine, frob the data into an actual
  813.  * scanline and call bitblt on the complete scan line instead of SetPixel.
  814.  */
  815.  
  816. /* Write a horizontal span of RGBA color pixels with a boolean mask. */
  817. static void write_rgba_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
  818.                              const GLubyte rgba[][4], const GLubyte mask[] )
  819. {
  820.     STARTPROFILE
  821.     PWMC    pwc = Current;
  822.  
  823.     if (pwc->rgb_flag==GL_TRUE)
  824.     {
  825.         GLuint i;
  826.         HDC DC=DD_GETDC;
  827.         y=FLIP(y);
  828.         if (mask) {
  829.             for (i=0; i<n; i++)
  830.                 if (mask[i])
  831.                     wmSetPixel(pwc, y, x + i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
  832.         }
  833.         else {
  834.             for (i=0; i<n; i++)
  835.                 wmSetPixel(pwc, y, x + i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
  836.         }
  837.         DD_RELEASEDC;
  838.     }
  839.     else
  840.     {
  841.         GLuint i;
  842.         BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  843.         y = FLIP(y);
  844.         if (mask) {
  845.             for (i=0; i<n; i++)
  846.                 if (mask[i])
  847.                     Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
  848.         }
  849.         else {
  850.             for (i=0; i<n; i++)
  851.                 Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
  852.         }
  853.     }
  854.     ENDPROFILE(write_rgba_span)
  855.  
  856. }
  857.  
  858. /* Write a horizontal span of RGB color pixels with a boolean mask. */
  859. static void write_rgb_span( const GLcontext* ctx,
  860.                             GLuint n, GLint x, GLint y,
  861.                             const GLubyte rgb[][3], const GLubyte mask[] )
  862. {
  863.     STARTPROFILE
  864.     PWMC    pwc = Current;
  865.  
  866.     if (pwc->rgb_flag==GL_TRUE)
  867.     {
  868.         GLuint i;
  869.         HDC DC=DD_GETDC;
  870.         y=FLIP(y);
  871.         if (mask) {
  872.             for (i=0; i<n; i++)
  873.                 if (mask[i])
  874.                     wmSetPixel(pwc, y, x + i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
  875.         }
  876.         else {
  877.             for (i=0; i<n; i++)
  878.                 wmSetPixel(pwc, y, x + i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
  879.         }
  880.         DD_RELEASEDC;
  881.     }
  882.     else
  883.     {
  884.         GLuint i;
  885.         BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  886.         y = FLIP(y);
  887.         if (mask) {
  888.             for (i=0; i<n; i++)
  889.                 if (mask[i])
  890.                     Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]));
  891.         }
  892.         else {
  893.             for (i=0; i<n; i++)
  894.                 Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]));
  895.         }
  896.     }
  897.     ENDPROFILE(write_rgb_span)
  898.  
  899. }
  900.  
  901. /*
  902. * Write a horizontal span of pixels with a boolean mask.  The current color
  903. * is used for all pixels.
  904. */
  905. static void write_mono_rgba_span( const GLcontext* ctx,
  906.                                   GLuint n, GLint x, GLint y,
  907.                                   const GLubyte mask[])
  908. {
  909.     STARTPROFILE
  910.     GLuint i;
  911.     HDC DC=DD_GETDC;
  912.     PWMC pwc = Current;
  913.     assert(Current->rgb_flag==GL_TRUE);
  914.     y=FLIP(y);
  915.     if(Current->rgb_flag==GL_TRUE){
  916.         for (i=0; i<n; i++)
  917.             if (mask[i])
  918.                 // Trying
  919.                 wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
  920.     }
  921.     else {
  922.         for (i=0; i<n; i++)
  923.             if (mask[i])
  924.                 SetPixel(DC, y, x+i, Current->pixel);
  925.     }
  926.     DD_RELEASEDC;
  927.     ENDPROFILE(write_mono_rgba_span)
  928. }
  929.  
  930.  
  931.  
  932. /**********************************************************************/
  933. /*****                   Array-based pixel drawing                *****/
  934. /**********************************************************************/
  935.  
  936.  
  937. /* Write an array of 32-bit index pixels with a boolean mask. */
  938. static void write_ci32_pixels( const GLcontext* ctx,
  939.                                GLuint n, const GLint x[], const GLint y[],
  940.                                const GLuint index[], const GLubyte mask[] )
  941. {
  942.    STARTPROFILE
  943.    GLuint i;
  944.    assert(Current->rgb_flag==GL_FALSE);
  945.    for (i=0; i<n; i++) {
  946.       if (mask[i]) {
  947.          BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
  948.          *Mem = index[i];
  949.       }
  950.    }
  951.    ENDPROFILE(write_ci32_pixels)
  952. }
  953.  
  954.  
  955.  
  956. /*
  957. * Write an array of pixels with a boolean mask.  The current color
  958. * index is used for all pixels.
  959. */
  960. static void write_mono_ci_pixels( const GLcontext* ctx,
  961.                                   GLuint n,
  962.                                   const GLint x[], const GLint y[],
  963.                                   const GLubyte mask[] )
  964. {
  965.    STARTPROFILE
  966.    GLuint i;
  967.    assert(Current->rgb_flag==GL_FALSE);
  968.    for (i=0; i<n; i++) {
  969.       if (mask[i]) {
  970.          BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
  971.          *Mem = Current->pixel;
  972.       }
  973.    }
  974.    ENDPROFILE(write_mono_ci_pixels)
  975. }
  976.  
  977.  
  978.  
  979. /* Write an array of RGBA pixels with a boolean mask. */
  980. static void write_rgba_pixels( const GLcontext* ctx,
  981.                                GLuint n, const GLint x[], const GLint y[],
  982.                                const GLubyte rgba[][4], const GLubyte mask[] )
  983. {
  984.     STARTPROFILE
  985.         GLuint i;
  986.     PWMC    pwc = Current;
  987.     HDC DC=DD_GETDC;
  988.     assert(Current->rgb_flag==GL_TRUE);
  989.     for (i=0; i<n; i++)
  990.        if (mask[i])
  991.           wmSetPixel(pwc, FLIP(y[i]),x[i],rgba[i][RCOMP],rgba[i][GCOMP],rgba[i][BCOMP]);
  992.     DD_RELEASEDC;
  993.     ENDPROFILE(write_rgba_pixels)
  994. }
  995.  
  996.  
  997.  
  998. /*
  999. * Write an array of pixels with a boolean mask.  The current color
  1000. * is used for all pixels.
  1001. */
  1002. static void write_mono_rgba_pixels( const GLcontext* ctx,
  1003.                                     GLuint n,
  1004.                                     const GLint x[], const GLint y[],
  1005.                                     const GLubyte mask[] )
  1006. {
  1007.     STARTPROFILE
  1008.     GLuint i;
  1009.     PWMC    pwc = Current;
  1010.     HDC DC=DD_GETDC;
  1011.     assert(Current->rgb_flag==GL_TRUE);
  1012.     for (i=0; i<n; i++)
  1013.         if (mask[i])
  1014.             wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel),
  1015.                        GetGValue(Current->pixel), GetBValue(Current->pixel));
  1016.     DD_RELEASEDC;
  1017.     ENDPROFILE(write_mono_rgba_pixels)
  1018. }
  1019.  
  1020.  
  1021.  
  1022. /**********************************************************************/
  1023. /*****            Read spans/arrays of pixels                     *****/
  1024. /**********************************************************************/
  1025.  
  1026.  
  1027. /* Read a horizontal span of color-index pixels. */
  1028. static void read_ci32_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
  1029.                             GLuint index[])
  1030. {
  1031.    STARTPROFILE
  1032.    GLuint i;
  1033.    BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
  1034.    assert(Current->rgb_flag==GL_FALSE);
  1035.    for (i=0; i<n; i++)
  1036.       index[i]=Mem[i];
  1037.    ENDPROFILE(read_ci32_span)
  1038. }
  1039.  
  1040.  
  1041.  
  1042.  
  1043. /* Read an array of color index pixels. */
  1044. static void read_ci32_pixels( const GLcontext* ctx,
  1045.                               GLuint n, const GLint x[], const GLint y[],
  1046.                               GLuint indx[], const GLubyte mask[] )
  1047. {
  1048.    STARTPROFILE
  1049.    GLuint i;
  1050.    assert(Current->rgb_flag==GL_FALSE);
  1051.    for (i=0; i<n; i++) {
  1052.       if (mask[i]) {
  1053.          indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
  1054.       }
  1055.    }
  1056.    ENDPROFILE(read_ci32_pixels)
  1057. }
  1058.  
  1059.  
  1060.  
  1061. /* Read a horizontal span of color pixels. */
  1062. static void read_rgba_span( const GLcontext* ctx,
  1063.                             GLuint n, GLint x, GLint y,
  1064.                             GLubyte rgba[][4] )
  1065. {
  1066.    STARTPROFILE
  1067.    UINT i;
  1068.    COLORREF Color;
  1069.    HDC DC=DD_GETDC;
  1070.    assert(Current->rgb_flag==GL_TRUE);
  1071.    y=FLIP(y);
  1072.    for (i=0; i<n; i++) {
  1073.       Color=GetPixel(DC,x+i,y);
  1074.       rgba[i][RCOMP] = GetRValue(Color);
  1075.       rgba[i][GCOMP] = GetGValue(Color);
  1076.       rgba[i][BCOMP] = GetBValue(Color);
  1077.       rgba[i][ACOMP] = 255;
  1078.    }
  1079.    DD_RELEASEDC;
  1080. // Brian P. Has mentioned to comment this out.
  1081. //   memset(alpha,0,n*sizeof(GLubyte));
  1082.    ENDPROFILE(read_rgba_span)
  1083. }
  1084.  
  1085.  
  1086. /* Read an array of color pixels. */
  1087. static void read_rgba_pixels( const GLcontext* ctx,
  1088.                               GLuint n, const GLint x[], const GLint y[],
  1089.                               GLubyte rgba[][4], const GLubyte mask[] )
  1090. {
  1091.    STARTPROFILE
  1092.    GLuint i;
  1093.    COLORREF Color;
  1094.    HDC DC=DD_GETDC;
  1095.    assert(Current->rgb_flag==GL_TRUE);
  1096.    for (i=0; i<n; i++) {
  1097.       if (mask[i]) {
  1098.          Color=GetPixel(DC,x[i],FLIP(y[i]));
  1099.          rgba[i][RCOMP] = GetRValue(Color);
  1100.          rgba[i][GCOMP] = GetGValue(Color);
  1101.          rgba[i][BCOMP] = GetBValue(Color);
  1102.          rgba[i][ACOMP] = 255;
  1103.       }
  1104.    }
  1105.    DD_RELEASEDC;
  1106. // Brian P. has mentioned to comment this out.
  1107. //   memset(alpha,0,n*sizeof(GLint));
  1108.    ENDPROFILE(read_rgba_pixels)
  1109. }
  1110.  
  1111.  
  1112.  
  1113. /**********************************************************************/
  1114. /**********************************************************************/
  1115.  
  1116.  
  1117. static const char *renderer_string(void)
  1118. {
  1119.    return "Windows";
  1120. }
  1121.  
  1122.  
  1123.  
  1124. void setup_DD_pointers( GLcontext* ctx )
  1125. {
  1126.     ctx->Driver.RendererString = renderer_string;
  1127.     ctx->Driver.UpdateState = setup_DD_pointers;
  1128.     ctx->Driver.GetBufferSize = buffer_size;
  1129.     ctx->Driver.Finish = finish;
  1130.     ctx->Driver.Flush = flush;
  1131.  
  1132.     ctx->Driver.ClearIndex = clear_index;
  1133.     ctx->Driver.ClearColor = clear_color;
  1134.     ctx->Driver.Clear = clear;
  1135.  
  1136.     ctx->Driver.Index = set_index;
  1137.     ctx->Driver.Color = set_color;
  1138.     ctx->Driver.IndexMask = index_mask;
  1139.     ctx->Driver.ColorMask = color_mask;
  1140.  
  1141.     ctx->Driver.LogicOp = logicop;
  1142.     ctx->Driver.Dither = dither;
  1143.  
  1144.     ctx->Driver.SetBuffer = set_buffer;
  1145.     ctx->Driver.GetBufferSize = buffer_size;
  1146.  
  1147.     ctx->Driver.PointsFunc = choose_points_function(ctx);
  1148.     ctx->Driver.LineFunc = choose_line_function(ctx);
  1149.     ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
  1150.  
  1151.     /* Pixel/span writing functions: */
  1152.     ctx->Driver.WriteRGBASpan        = write_rgba_span;
  1153.     ctx->Driver.WriteRGBSpan         = write_rgb_span;
  1154.     ctx->Driver.WriteMonoRGBASpan    = write_mono_rgba_span;
  1155.     ctx->Driver.WriteRGBAPixels      = write_rgba_pixels;
  1156.     ctx->Driver.WriteMonoRGBAPixels  = write_mono_rgba_pixels;
  1157.     ctx->Driver.WriteCI32Span        = write_ci32_span;
  1158.     ctx->Driver.WriteCI8Span         = write_ci8_span;
  1159.     ctx->Driver.WriteMonoCISpan      = write_mono_ci_span;
  1160.     ctx->Driver.WriteCI32Pixels      = write_ci32_pixels;
  1161.     ctx->Driver.WriteMonoCIPixels    = write_mono_ci_pixels;
  1162.  
  1163.     ctx->Driver.ReadCI32Span        = read_ci32_span;
  1164.     ctx->Driver.ReadRGBASpan        = read_rgba_span;
  1165.     ctx->Driver.ReadCI32Pixels      = read_ci32_pixels;
  1166.     ctx->Driver.ReadRGBAPixels      = read_rgba_pixels;
  1167. }
  1168.  
  1169.  
  1170. /**********************************************************************/
  1171. /*****                  WMesa API Functions                       *****/
  1172. /**********************************************************************/
  1173.  
  1174.  
  1175.  
  1176. #define PAL_SIZE 256
  1177. static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
  1178. {
  1179.     STARTPROFILE
  1180.         int i;
  1181.     HDC hdc;
  1182.     struct
  1183.     {
  1184.         WORD Version;
  1185.         WORD NumberOfEntries;
  1186.         PALETTEENTRY aEntries[PAL_SIZE];
  1187.     } Palette =
  1188.     {
  1189.         0x300,
  1190.             PAL_SIZE
  1191.     };
  1192.     hdc=GetDC(NULL);
  1193.     if (Pal!=NULL)
  1194.         GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
  1195.     else
  1196.         GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
  1197.     if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
  1198.     {
  1199.         for(i = 0; i <PAL_SIZE; i++)
  1200.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1201.         Palette.aEntries[255].peRed = 255;
  1202.         Palette.aEntries[255].peGreen = 255;
  1203.         Palette.aEntries[255].peBlue = 255;
  1204.         Palette.aEntries[255].peFlags = 0;
  1205.         Palette.aEntries[0].peRed = 0;
  1206.         Palette.aEntries[0].peGreen = 0;
  1207.         Palette.aEntries[0].peBlue = 0;
  1208.         Palette.aEntries[0].peFlags = 0;
  1209.     }
  1210.     else
  1211.     {
  1212.         int nStaticColors;
  1213.         int nUsableColors;
  1214.         nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
  1215.         for (i=0; i<nStaticColors; i++)
  1216.             Palette.aEntries[i].peFlags = 0;
  1217.         nUsableColors = PAL_SIZE-nStaticColors;
  1218.         for (; i<nUsableColors; i++)
  1219.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1220.         for (; i<PAL_SIZE-nStaticColors; i++)
  1221.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1222.         for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
  1223.             Palette.aEntries[i].peFlags = 0;
  1224.     }
  1225.     ReleaseDC(NULL,hdc);
  1226.     for (i=0; i<PAL_SIZE; i++)
  1227.     {
  1228.         aRGB[i].rgbRed=Palette.aEntries[i].peRed;
  1229.         aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
  1230.         aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
  1231.         aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
  1232.     }
  1233.     ENDPROFILE(GetPalette)
  1234. }
  1235.  
  1236.  
  1237. WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal,
  1238.                                 GLboolean rgb_flag,
  1239.                                 GLboolean db_flag )
  1240. {
  1241.     RECT CR;
  1242.     WMesaContext c;
  1243.     GLboolean true_color_flag;
  1244.     c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
  1245.     if (!c)
  1246.         return NULL;
  1247.  
  1248.     c->Window=hWnd;
  1249.     c->hDC = GetDC(hWnd);
  1250.     true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
  1251. #ifdef DDRAW
  1252.     if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;
  1253. #endif
  1254.  
  1255.  
  1256. #ifdef DITHER
  1257.     if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
  1258.         c->dither_flag = GL_TRUE;
  1259.         c->hPalHalfTone = WinGCreateHalftonePalette();
  1260.     }
  1261.     else
  1262.         c->dither_flag = GL_FALSE;
  1263. #else
  1264.     c->dither_flag = GL_FALSE;
  1265. #endif
  1266.  
  1267.  
  1268.     if (rgb_flag==GL_FALSE)
  1269.     {
  1270.         c->rgb_flag = GL_FALSE;
  1271.         //    c->pixel = 1;
  1272.         c->db_flag = db_flag =GL_TRUE; // WinG requires double buffering
  1273.         printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
  1274.     }
  1275.     else
  1276.     {
  1277.         c->rgb_flag = GL_TRUE;
  1278.         //    c->pixel = 0;
  1279.     }
  1280.     GetClientRect(c->Window,&CR);
  1281.     c->width=CR.right;
  1282.     c->height=CR.bottom;
  1283.     if (db_flag)
  1284.     {
  1285.         c->db_flag = 1;
  1286.         /* Double buffered */
  1287. #ifndef DDRAW
  1288.         //  if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
  1289.         {
  1290.             wmCreateBackingStore(c, c->width, c->height);
  1291.  
  1292.         }
  1293. #endif
  1294.     }
  1295.     else
  1296.     {
  1297.         /* Single Buffered */
  1298.         if (c->rgb_flag)
  1299.             c->db_flag = 0;
  1300.     }
  1301. #ifdef DDRAW
  1302.     if (DDInit(c,hWnd) == GL_FALSE) {
  1303.         free( (void *) c );
  1304.         exit(1);
  1305.     }
  1306. #endif
  1307.  
  1308.  
  1309.     c->gl_visual = gl_create_visual(rgb_flag,
  1310.                                     GL_FALSE,   /* software alpha */
  1311.                                     db_flag,    /* db_flag */
  1312.                                     GL_FALSE,   /* stereo */
  1313.                                     16,         /* depth_bits */
  1314.                                     8,          /* stencil_bits */
  1315.                                     8,          /* accum_bits */
  1316.                                     0,          /* index bits */
  1317.                                     8,8,8,8 );  /* r, g, b, a bits */
  1318.  
  1319.     if (!c->gl_visual) {
  1320.         return NULL;
  1321.     }
  1322.  
  1323.     /* allocate a new Mesa context */
  1324.     c->gl_ctx = gl_create_context( c->gl_visual, NULL, c, GL_TRUE);
  1325.  
  1326.     if (!c->gl_ctx) {
  1327.         gl_destroy_visual( c->gl_visual );
  1328.         free(c);
  1329.         return NULL;
  1330.     }
  1331.  
  1332.     c->gl_buffer = gl_create_framebuffer( c->gl_visual );
  1333.     if (!c->gl_buffer) {
  1334.         gl_destroy_visual( c->gl_visual );
  1335.         gl_destroy_context( c->gl_ctx );
  1336.         free(c);
  1337.         return NULL;
  1338.     }
  1339.  
  1340.     c->gl_ctx->Driver.UpdateState = setup_DD_pointers;
  1341.  
  1342.     //  setup_DD_pointers(c->gl_ctx);
  1343.  
  1344.     return c;
  1345. }
  1346.  
  1347. void WMesaDestroyContext( void )
  1348. {
  1349.     WMesaContext c = Current;
  1350.     ReleaseDC(c->Window,c->hDC);
  1351.     WC = c;
  1352.     if(c->hPalHalfTone != NULL)
  1353.         DeleteObject(c->hPalHalfTone);
  1354.     gl_destroy_visual( c->gl_visual );
  1355.     gl_destroy_framebuffer( c->gl_buffer );
  1356.     gl_destroy_context( c->gl_ctx );
  1357.  
  1358.     if (c->db_flag)
  1359. #ifdef DDRAW
  1360.         DDFree(c);
  1361. #else
  1362.     wmDeleteBackingStore(c);
  1363. #endif
  1364.     free( (void *) c );
  1365.     //Following code is added to enable parallel render
  1366.     // Parallel render only work in double buffer mode
  1367. #if !defined(NO_PARALLEL)
  1368.     if(parallelMachine)
  1369.         PRDestroyRenderBuffer();
  1370. #endif
  1371.     // End modification
  1372. }
  1373.  
  1374.  
  1375.  
  1376. void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )
  1377. {
  1378.     if(!c){
  1379.         Current = c;
  1380.         return;
  1381.     }
  1382.  
  1383.     //
  1384.     // A little optimization
  1385.     // If it already is current,
  1386.     // don't set it again
  1387.     //
  1388.     if(Current == c)
  1389.         return;
  1390.  
  1391.     //gl_set_context( c->gl_ctx );
  1392.     gl_make_current(c->gl_ctx, c->gl_buffer);
  1393.     setup_DD_pointers(c->gl_ctx);
  1394.     Current = c;
  1395.     if (Current->gl_ctx->Viewport.Width==0) {
  1396.         /* initialize viewport to window size */
  1397.         gl_Viewport( Current->gl_ctx,
  1398.             0, 0, Current->width, Current->height );
  1399.     }
  1400.     if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
  1401.         WMesaPaletteChange(c->hPalHalfTone);
  1402.     }
  1403. }
  1404.  
  1405.  
  1406.  
  1407. void /*APIENTRY*/ WMesaSwapBuffers( void )
  1408. {
  1409.     HDC DC = Current->hDC;
  1410.     if (Current->db_flag)
  1411.         wmFlush(Current);
  1412. }
  1413.  
  1414.  
  1415.  
  1416. void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)
  1417. {
  1418.     int vRet;
  1419.     LPPALETTEENTRY pPal;
  1420.     if (Current && (Current->rgb_flag==GL_FALSE || Current->dither_flag == GL_TRUE))
  1421.     {
  1422.         pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
  1423.         Current->hPal=Pal;
  1424.         //  GetPaletteEntries( Pal, 0, 256, pPal );
  1425.         GetPalette( Pal, pPal );
  1426. #ifdef DDRAW
  1427.         Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,
  1428.             pPal, &(Current->lpDDPal), NULL);
  1429.         if (Current->lpDDPal)
  1430.             Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,Current->lpDDPal);
  1431. #else
  1432.         vRet = SetDIBColorTable(Current->dib.hDC,0,256,pPal);
  1433. #endif
  1434.         free( pPal );
  1435.     }
  1436.  
  1437. }
  1438.  
  1439.  
  1440.  
  1441.  
  1442. static unsigned char threeto8[8] = {
  1443.     0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
  1444. };
  1445.  
  1446. static unsigned char twoto8[4] = {
  1447.     0, 0x55, 0xaa, 0xff
  1448. };
  1449.  
  1450. static unsigned char oneto8[2] = {
  1451.     0, 255
  1452. };
  1453.  
  1454. static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
  1455. {
  1456.     unsigned char val;
  1457.  
  1458.     val = i >> shift;
  1459.     switch (nbits) {
  1460.  
  1461.     case 1:
  1462.         val &= 0x1;
  1463.         return oneto8[val];
  1464.  
  1465.     case 2:
  1466.         val &= 0x3;
  1467.         return twoto8[val];
  1468.  
  1469.     case 3:
  1470.         val &= 0x7;
  1471.         return threeto8[val];
  1472.  
  1473.     default:
  1474.         return 0;
  1475.     }
  1476. }
  1477.  
  1478. void /*WINAPI*/ wmCreatePalette( PWMC pwdc )
  1479. {
  1480.     /* Create a compressed and re-expanded 3:3:2 palette */
  1481.     int            i;
  1482.     LOGPALETTE     *pPal;
  1483.     BYTE           rb, rs, gb, gs, bb, bs;
  1484.  
  1485.     pwdc->nColors = 0x100;
  1486.  
  1487.     pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
  1488.     memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
  1489.  
  1490.     pPal->palVersion = 0x300;
  1491.  
  1492.     rb = REDBITS;
  1493.     rs = REDSHIFT;
  1494.     gb = GREENBITS;
  1495.     gs = GREENSHIFT;
  1496.     bb = BLUEBITS;
  1497.     bs = BLUESHIFT;
  1498.  
  1499.     if (pwdc->db_flag) {
  1500.  
  1501.         /* Need to make two palettes: one for the screen DC and one for the DIB. */
  1502.         pPal->palNumEntries = pwdc->nColors;
  1503.         for (i = 0; i < pwdc->nColors; i++) {
  1504.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1505.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1506.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1507.             pPal->palPalEntry[i].peFlags = 0;
  1508.         }
  1509.         pwdc->hGLPalette = CreatePalette( pPal );
  1510.         pwdc->hPalette = CreatePalette( pPal );
  1511.     }
  1512.  
  1513.     else {
  1514.         pPal->palNumEntries = pwdc->nColors;
  1515.         for (i = 0; i < pwdc->nColors; i++) {
  1516.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1517.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1518.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1519.             pPal->palPalEntry[i].peFlags = 0;
  1520.         }
  1521.         pwdc->hGLPalette = CreatePalette( pPal );
  1522.     }
  1523.  
  1524.     free(pPal);
  1525.  
  1526. }
  1527.  
  1528. void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
  1529. {
  1530.     if(Current->db_flag){
  1531.         LPBYTE  lpb = pwc->pbPixels;
  1532.         LPDWORD lpdw;
  1533.         LPWORD  lpw;
  1534.         UINT    nBypp = pwc->cColorBits / 8;
  1535.         UINT    nOffset = iPixel % nBypp;
  1536.  
  1537.         // Move the pixel buffer pointer to the scanline that we
  1538.         // want to access
  1539.  
  1540.         //      pwc->dib.fFlushed = FALSE;
  1541.  
  1542.         lpb += pwc->ScanWidth * iScanLine;
  1543.         // Now move to the desired pixel
  1544.         lpb += iPixel * nBypp;
  1545.         lpb = PIXELADDR(iPixel, iScanLine);
  1546.         lpdw = (LPDWORD)lpb;
  1547.         lpw = (LPWORD)lpb;
  1548.  
  1549.         if(nBypp == 1){
  1550.             if(pwc->dither_flag)
  1551.                 *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
  1552.             else
  1553.                 *lpb = BGR8(r,g,b);
  1554.         }
  1555.         else if(nBypp == 2)
  1556.             *lpw = BGR16(r,g,b);
  1557.         else if (nBypp == 3){
  1558.             *lpdw = BGR24(r,g,b);
  1559.         }
  1560.         else if (nBypp == 4)
  1561.             *lpdw = BGR32(r,g,b);
  1562.     }
  1563.     else{
  1564.         HDC DC = DD_GETDC;
  1565.         SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));
  1566.         DD_RELEASEDC;
  1567.     }
  1568. }
  1569.  
  1570. void /*WINAPI*/ wmCreateDIBSection(
  1571.                                    HDC   hDC,
  1572.                                    PWMC pwc,    // handle of device context
  1573.                                    CONST BITMAPINFO *pbmi,  // address of structure containing bitmap size, format, and color data
  1574.                                    UINT iUsage  // color data type indicator: RGB values or palette indices
  1575.                                    )
  1576. {
  1577.     DWORD   dwSize = 0;
  1578.     DWORD   dwScanWidth;
  1579.     UINT    nBypp = pwc->cColorBits / 8;
  1580.     HDC     hic;
  1581.  
  1582.     dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
  1583.  
  1584.     pwc->ScanWidth =pwc->pitch = dwScanWidth;
  1585.  
  1586.     if (stereo_flag)
  1587.         pwc->ScanWidth = 2* pwc->pitch;
  1588.  
  1589.     dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
  1590.  
  1591.     pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
  1592.         NULL,
  1593.         PAGE_READWRITE | SEC_COMMIT,
  1594.         0,
  1595.         dwSize,
  1596.         NULL);
  1597.  
  1598.     if (!pwc->dib.hFileMap)
  1599.         return;
  1600.  
  1601.     pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
  1602.         FILE_MAP_ALL_ACCESS,
  1603.         0,
  1604.         0,
  1605.         0);
  1606.  
  1607.     if(!pwc->dib.base){
  1608.         CloseHandle(pwc->dib.hFileMap);
  1609.         return;
  1610.     }
  1611.  
  1612.     //  pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
  1613.  
  1614.     //  pwc->dib.hDC = CreateCompatibleDC(hDC);
  1615.  
  1616.     CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
  1617.  
  1618.     hic = CreateIC("display", NULL, NULL, NULL);
  1619.     pwc->dib.hDC = CreateCompatibleDC(hic);
  1620.  
  1621.  
  1622.     /*  pwc->hbmDIB = CreateDIBitmap(hic,
  1623.     &(pwc->bmi.bmiHeader),
  1624.     CBM_INIT,
  1625.     pwc->pbPixels,
  1626.     &(pwc->bmi),
  1627.     DIB_RGB_COLORS);
  1628.     */
  1629.     pwc->hbmDIB = CreateDIBSection(hic,
  1630.         &(pwc->bmi),
  1631.         (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
  1632.         &(pwc->pbPixels),
  1633.         pwc->dib.hFileMap,
  1634.         0);
  1635.         /*
  1636.         pwc->hbmDIB = CreateDIBSection(hic,
  1637.         &(pwc->bmi),
  1638.         DIB_RGB_COLORS,
  1639.         &(pwc->pbPixels),
  1640.         pwc->dib.hFileMap,
  1641.         0);
  1642.     */
  1643.     pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
  1644.     pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
  1645.  
  1646.     DeleteDC(hic);
  1647.  
  1648.     return;
  1649.  
  1650. }
  1651.  
  1652. //
  1653. // Blit memory DC to screen DC
  1654. //
  1655. BOOL /*WINAPI*/ wmFlush(PWMC pwc)
  1656. {
  1657.     BOOL    bRet = 0;
  1658.     DWORD   dwErr = 0;
  1659. #ifdef DDRAW
  1660.     HRESULT             ddrval;
  1661. #endif
  1662.  
  1663.     // Now search through the torus frames and mark used colors
  1664.     if(pwc->db_flag){
  1665. #ifdef DDRAW
  1666.         if (pwc->lpDDSOffScreen == NULL)
  1667.             if(DDCreateOffScreen(pwc) == GL_FALSE)
  1668.                 return;
  1669.  
  1670.             pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
  1671.  
  1672.             while( 1 )
  1673.             {
  1674.                 ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
  1675.                     &(pwc->rectSurface), pwc->lpDDSOffScreen, &(pwc->rectOffScreen), 0, NULL );
  1676.  
  1677.                 if( ddrval == DD_OK )
  1678.                 {
  1679.                     break;
  1680.                 }
  1681.                 if( ddrval == DDERR_SURFACELOST )
  1682.                 {
  1683.                     if(!DDRestoreAll(pwc))
  1684.                     {
  1685.                         break;
  1686.                     }
  1687.                 }
  1688.                 if( ddrval != DDERR_WASSTILLDRAWING )
  1689.                 {
  1690.                     break;
  1691.                 }
  1692.             }
  1693.  
  1694.             while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
  1695.                 NULL, &(pwc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
  1696.                 ;
  1697.  
  1698.             if(ddrval != DD_OK)
  1699.                 dwErr = GetLastError();
  1700. #else
  1701.             bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
  1702.                 pwc->dib.hDC, 0, 0, SRCCOPY);
  1703. #endif
  1704.     }
  1705.  
  1706.     return(TRUE);
  1707.  
  1708. }
  1709.  
  1710.  
  1711. // The following code is added by Li Wei to enable stereo display
  1712.  
  1713. #if !defined(NO_STEREO)
  1714.  
  1715. void WMesaShowStereo(GLuint list)
  1716. {
  1717.  
  1718.     GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
  1719.     GLfloat cm[16];
  1720.     GLint matrix_mode;
  1721.     // Must use double Buffer
  1722.     if( ! Current-> db_flag )
  1723.         return;
  1724.  
  1725.  
  1726.     glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
  1727.  
  1728.     //  glPushMatrix();  //****
  1729.     WMesaViewport(Current->gl_ctx,0,Current->height/2,Current->width,Current->height/2);
  1730.     //  Current->gl_ctx->NewState = 0;
  1731.  
  1732.     //  glViewport(0,0,Current->width,Current->height/2);
  1733.     if(matrix_mode!=GL_MODELVIEW)
  1734.         glMatrixMode(GL_MODELVIEW);
  1735.  
  1736.     glGetFloatv(GL_MODELVIEW_MATRIX,cm);
  1737.     glLoadIdentity();
  1738.     gluLookAt(viewDistance/2,0.0,0.0 ,
  1739.         viewDistance/2,0.0,-1.0,
  1740.         0.0,1.0,0.0 );
  1741.     //  glTranslatef(viewDistance/2.0,0.,0.);
  1742.     glMultMatrixf( cm );
  1743.  
  1744.     Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
  1745.     //glPushMatrix();
  1746.     glCallList( list );
  1747.     //glPopMatrix();
  1748.  
  1749.     glGetFloatv(GL_MODELVIEW_MATRIX,cm);
  1750.     glLoadIdentity();
  1751.     gluLookAt(-viewDistance/2,0.0,0.0 ,
  1752.         -viewDistance/2,0.0,-1.0,
  1753.         0.0,1.0,0.0 );
  1754.     //  glTranslatef(-viewDistance/2.0,0.,0.);
  1755.     glMultMatrixf(cm);
  1756.  
  1757.     Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
  1758.     glCallList(list);
  1759.     if(matrix_mode!=GL_MODELVIEW)
  1760.         glMatrixMode(matrix_mode);
  1761.  
  1762.     //  glPopMatrix();
  1763.     glFlush();
  1764.  
  1765.     WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
  1766.     //  Current->gl_ctx->NewState = 0;
  1767.     WMesaSwapBuffers();
  1768.  
  1769. }
  1770.  
  1771. void toggleStereoMode()
  1772. {
  1773.     if(!Current->db_flag)
  1774.         return;
  1775.     if(!stereo_flag){
  1776.         stereo_flag = 1;
  1777.         if(stereoBuffer==GL_FALSE)
  1778. #if !defined(NO_PARALLEL)
  1779.             if(!parallelFlag)
  1780. #endif
  1781.             {
  1782.                 Current->ScanWidth = Current->pitch*2;
  1783.             }
  1784.     }
  1785.     else {
  1786.         stereo_flag = 0;
  1787. #if !defined(NO_PARALLEL)
  1788.         if(!parallelFlag)
  1789. #endif
  1790.             Current->ScanWidth = Current->pitch;
  1791.         Current->pbPixels = Current->addrOffScreen;
  1792.     }
  1793. }
  1794.  
  1795. /* if in stereo mode, the following function is called */
  1796. void glShowStereo(GLuint list)
  1797. {
  1798.     WMesaShowStereo(list);
  1799. }
  1800.  
  1801. #endif // End if NO_STEREO not defined
  1802.  
  1803. #if !defined(NO_PARALLEL)
  1804.  
  1805. void toggleParallelMode(void)
  1806. {
  1807.     if(!parallelFlag){
  1808.         parallelFlag = GL_TRUE;
  1809.         if(parallelMachine==GL_FALSE){
  1810.             PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
  1811.                 Current->cColorBits/8,
  1812.                 Current->width ,Current->height,
  1813.                 Current->ScanWidth,
  1814.                 Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
  1815.             parallelMachine = GL_TRUE;
  1816.         }
  1817.     }
  1818.     else {
  1819.         parallelFlag = GL_FALSE;
  1820.         if(parallelMachine==GL_TRUE){
  1821.             PRDestroyRenderBuffer();
  1822.             parallelMachine=GL_FALSE;
  1823.             ReadyForNextFrame = GL_TRUE;
  1824.         }
  1825.  
  1826.         /***********************************************
  1827.         // Seems something wrong!!!!
  1828.         ************************************************/
  1829.  
  1830.         WMesaMakeCurrent(Current);
  1831. #if !defined(NO_STEREO)
  1832.         stereo_flag = GL_FALSE ;
  1833. #endif
  1834.     }
  1835. }
  1836.  
  1837. void PRShowRenderResult(void)
  1838. {
  1839.     int flag = 0;
  1840.     if(!glImageRendered())
  1841.         return;
  1842.  
  1843.     if (parallelFlag)
  1844.     {
  1845.         WMesaSwapBuffers();
  1846.     }
  1847.  
  1848. }
  1849. #endif //End if NO_PARALLEL not defined
  1850.  
  1851. //end modification
  1852.  
  1853. BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
  1854. {
  1855.     char unsigned redtemp, greentemp, bluetemp, paletteindex;
  1856.  
  1857.     //*** now, look up each value in the halftone matrix
  1858.     //*** using an 8x8 ordered dither.
  1859.     redtemp = aDividedBy51[red]
  1860.         + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
  1861.         + scanline%8]);
  1862.     greentemp = aDividedBy51[(char unsigned)green]
  1863.         + (aModulo51[green] > aHalftone8x8[
  1864.         (pixel%8)*8 + scanline%8]);
  1865.     bluetemp = aDividedBy51[(char unsigned)blue]
  1866.         + (aModulo51[blue] > aHalftone8x8[
  1867.         (pixel%8)*8 +scanline%8]);
  1868.  
  1869.     //*** recombine the halftoned rgb values into a palette index
  1870.     paletteindex =
  1871.         redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
  1872.  
  1873.     //*** and translate through the wing halftone palette
  1874.     //*** translation vector to give the correct value.
  1875.     return aWinGHalftoneTranslation[paletteindex];
  1876. }
  1877.  
  1878. #ifdef DDRAW
  1879. /*
  1880. * restoreAll
  1881. *
  1882. * restore all lost objects
  1883. */
  1884. HRESULT DDRestoreAll( WMesaContext wc )
  1885. {
  1886.     HRESULT     ddrval;
  1887.  
  1888.     ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
  1889.     if( ddrval == DD_OK )
  1890.     {
  1891.         ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
  1892.     }
  1893.     return ddrval;
  1894.  
  1895. } /* restoreAll */
  1896.  
  1897.  
  1898.   /*
  1899.   * This function is called if the initialization function fails
  1900. */
  1901. BOOL initFail( HWND hwnd, WMesaContext wc )
  1902. {
  1903.     DDFree(wc);
  1904.     MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
  1905.     return FALSE;
  1906.  
  1907. } /* initFail */
  1908.  
  1909.  
  1910. static void DDDeleteOffScreen(WMesaContext wc)
  1911. {
  1912.     if( wc->lpDDSOffScreen != NULL )
  1913.     {
  1914.         wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
  1915.         wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
  1916.         wc->lpDDSOffScreen = NULL;
  1917.     }
  1918.  
  1919. }
  1920.  
  1921. static void DDFreePrimarySurface(WMesaContext wc)
  1922. {
  1923.     if( wc->lpDDSPrimary != NULL )
  1924.     {
  1925.         if(wc->db_flag == GL_FALSE)
  1926.             wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
  1927.         wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
  1928.         wc->lpDDSPrimary = NULL;
  1929.     }
  1930. }
  1931.  
  1932. static BOOL DDCreatePrimarySurface(WMesaContext wc)
  1933. {
  1934.     HRESULT ddrval;
  1935.     DDSCAPS             ddscaps;
  1936.     wc->ddsd.dwSize = sizeof( wc->ddsd );
  1937.     wc->ddsd.dwFlags = DDSD_CAPS;
  1938.     wc->ddsd.ddsCaps.dwCaps =   DDSCAPS_PRIMARYSURFACE;
  1939.  
  1940.     ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd), &(wc->lpDDSPrimary), NULL );
  1941.     if( ddrval != DD_OK )
  1942.     {
  1943.         return initFail(wc->hwnd , wc);
  1944.     }
  1945.     if(wc->db_flag == GL_FALSE)
  1946.         wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, wc->hDC);
  1947.     return TRUE;
  1948. }
  1949.  
  1950. static BOOL DDCreateOffScreen(WMesaContext wc)
  1951. {
  1952.     POINT   pt;
  1953.     HRESULT     ddrval;
  1954.     if(wc->lpDD == NULL)
  1955.         return FALSE;
  1956.     GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
  1957.     wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  1958.     wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  1959.     wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
  1960.     wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
  1961.  
  1962.     ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd), &(wc->lpDDSOffScreen), NULL );
  1963.     if( ddrval != DD_OK )
  1964.     {
  1965.         return FALSE;
  1966.     }
  1967.  
  1968.     while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
  1969.         ;
  1970.     //  while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
  1971.     ;
  1972.     if(wc->ddsd.lpSurface==NULL)
  1973.         return initFail(wc->hwnd, wc);
  1974.  
  1975.     wc->ScreenMem = wc->pbPixels = wc->addrOffScreen = (PBYTE)(wc->ddsd.lpSurface);
  1976.     wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
  1977.     if (stereo_flag)
  1978.         wc->ScanWidth = wc->ddsd.lPitch*2;
  1979.  
  1980.     GetClientRect( wc->hwnd, &(wc->rectSurface) );
  1981.     pt.x = pt.y = 0;
  1982.     ClientToScreen( wc->hwnd, &pt );
  1983.     OffsetRect(&(wc->rectSurface), pt.x, pt.y);
  1984.     wmSetPixelFormat(wc, wc->hDC);
  1985.     return TRUE;
  1986. }
  1987.  
  1988. /*
  1989. * doInit - do work required for every instance of the application:
  1990. *                create the window, initialize data
  1991. */
  1992. static BOOL DDInit( WMesaContext wc, HWND hwnd)
  1993. {
  1994.     HRESULT             ddrval;
  1995.     DWORD dwFrequency;
  1996.  
  1997.     LPDIRECTDRAW            lpDD;           // DirectDraw object
  1998.     LPDIRECTDRAW2            lpDD2;
  1999.  
  2000.  
  2001.     wc->fullScreen = displayOptions.fullScreen;
  2002.     wc->gMode = displayOptions.mode;
  2003.     wc->hwnd = hwnd;
  2004.     stereo_flag = displayOptions.stereo;
  2005.     if(wc->db_flag!= GL_TRUE)
  2006.         stereo_flag = GL_FALSE;
  2007.         /*
  2008.         * create the main DirectDraw object
  2009.     */
  2010.     ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
  2011.     if( ddrval != DD_OK )
  2012.     {
  2013.         return initFail(hwnd,wc);
  2014.     }
  2015.  
  2016.     // Get exclusive mode if requested
  2017.     if(wc->fullScreen)
  2018.     {
  2019.         ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  2020.     }
  2021.     else
  2022.     {
  2023.         ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_NORMAL );
  2024.     }
  2025.     if( ddrval != DD_OK )
  2026.     {
  2027.         return initFail(hwnd , wc);
  2028.     }
  2029.  
  2030.  
  2031.     /*  ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
  2032.     (LPVOID *)((wc->lpDD2)));
  2033.  
  2034.     */
  2035.     if(ddrval != DD_OK)
  2036.         return initFail(hwnd , wc);
  2037.  
  2038.  
  2039.     //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
  2040.     //  wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
  2041.     switch( wc->gMode )
  2042.     {
  2043.     case 1:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480, displayOptions.bpp); break;
  2044.     case 2:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600, displayOptions.bpp); break;
  2045.     case 3:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768, displayOptions.bpp); break;
  2046.     case 4:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864, displayOptions.bpp); break;
  2047.     case 5:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024, displayOptions.bpp); break;
  2048.     }
  2049.  
  2050.     if( ddrval != DD_OK )
  2051.     {
  2052.         printf("Can't modify display mode, current mode used\n");
  2053.         //        return initFail(hwnd , wc);
  2054.     }
  2055.     //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
  2056.     switch(ddrval){
  2057.     case DDERR_INVALIDOBJECT:
  2058.         break;
  2059.     case DDERR_INVALIDPARAMS:
  2060.         break;
  2061.     case DDERR_UNSUPPORTEDMODE:
  2062.         ;
  2063.     }
  2064.  
  2065.     if(DDCreatePrimarySurface(wc) == GL_FALSE)
  2066.         return initFail(hwnd, wc);
  2067.  
  2068.     if(wc->db_flag)
  2069.         return DDCreateOffScreen(wc);
  2070. } /* DDInit */
  2071.  
  2072. static void DDFree( WMesaContext wc)
  2073. {
  2074.     if( wc->lpDD != NULL )
  2075.     {
  2076.         DDFreePrimarySurface(wc);
  2077.         DDDeleteOffScreen(wc);
  2078.         wc->lpDD->lpVtbl->Release(wc->lpDD);
  2079.         wc->lpDD = NULL;
  2080.     }
  2081.     // Clean up the screen on exit
  2082.     RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
  2083.         RDW_ALLCHILDREN );
  2084.  
  2085. }
  2086. #endif
  2087.  
  2088. void WMesaMove(void)
  2089. {
  2090.     WMesaContext wc = Current;
  2091.     POINT   pt;
  2092.     if (Current != NULL){
  2093.         GetClientRect( wc->hwnd, &(wc->rectSurface) );
  2094.         pt.x = pt.y = 0;
  2095.         ClientToScreen( wc->hwnd, &pt );
  2096.         OffsetRect(&(wc->rectSurface), pt.x, pt.y);
  2097.     }
  2098. }
  2099.  
  2100.  
  2101.  
  2102. /*
  2103. * Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable
  2104. * shortcut.
  2105. */
  2106. #define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )
  2107.  
  2108.  
  2109. /**********************************************************************/
  2110. /***                   Triangle rendering                            ***/
  2111. /**********************************************************************/
  2112.  
  2113. /*
  2114.  * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
  2115.  */
  2116. static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
  2117.                                        GLuint v0, GLuint v1, GLuint v2,
  2118.                                        GLuint pv )
  2119. {
  2120.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2121. #define INTERP_Z 1
  2122. #define INTERP_RGB 1
  2123. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2124. #define PIXEL_TYPE GLuint
  2125.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2126. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2127. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2128.     {                                   \
  2129.     GLint i, len = RIGHT-LEFT;                      \
  2130.     for (i=0;i<len;i++) {                       \
  2131.     GLdepth z = FixedToDepth(ffz);                  \
  2132.     if (z < zRow[i]) {                      \
  2133.     pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),    \
  2134.     FixedToInt(ffb) );          \
  2135.     zRow[i] = z;                            \
  2136.     }                                   \
  2137.     ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
  2138.     ffz += fdzdx;                           \
  2139.     }                                   \
  2140.     }
  2141. #ifdef WIN32
  2142.     #include "..\tritemp.h"
  2143. #else
  2144.     #include "tritemp.h"
  2145. #endif
  2146. }
  2147.  
  2148.  
  2149. /*
  2150. * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
  2151. */
  2152. static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
  2153.                                      GLuint v0, GLuint v1, GLuint v2,
  2154.                                      GLuint pv )
  2155. {
  2156.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2157. #define INTERP_Z 1
  2158. #define INTERP_RGB 1
  2159. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2160. #define PIXEL_TYPE GLuint
  2161.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2162. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2163. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2164.     {                                   \
  2165.     GLint i, len = RIGHT-LEFT;                      \
  2166.     for (i=0;i<len;i++) {                       \
  2167.     GLdepth z = FixedToDepth(ffz);                  \
  2168.     if (z < zRow[i]) {                      \
  2169.     pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),    \
  2170.     FixedToInt(ffb) );          \
  2171.     zRow[i] = z;                            \
  2172.     }                                   \
  2173.     ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
  2174.     ffz += fdzdx;                           \
  2175.     }                                   \
  2176.     }
  2177. #ifdef WIN32
  2178.     #include "..\tritemp.h"
  2179. #else
  2180.     #include "tritemp.h"
  2181. #endif
  2182. }
  2183.  
  2184.  
  2185.  
  2186. /*
  2187. * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
  2188. */
  2189. static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
  2190.                                      GLuint v0, GLuint v1, GLuint v2,
  2191.                                      GLuint pv )
  2192. {
  2193.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2194. #define INTERP_Z 1
  2195. #define INTERP_RGB 1
  2196. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  2197. #define PIXEL_TYPE GLushort
  2198.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2199. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2200. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2201.     {                                   \
  2202.     GLint i, len = RIGHT-LEFT;                      \
  2203.     for (i=0;i<len;i++) {                       \
  2204.     GLdepth z = FixedToDepth(ffz);                  \
  2205.     if (z < zRow[i]) {                      \
  2206.     pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),    \
  2207.     FixedToInt(ffb) );          \
  2208.     zRow[i] = z;                            \
  2209.     }                                   \
  2210.     ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
  2211.     ffz += fdzdx;                           \
  2212.     }                                   \
  2213.     }
  2214. #ifdef WIN32
  2215.     #include "..\tritemp.h"
  2216. #else
  2217.     #include "tritemp.h"
  2218. #endif
  2219. }
  2220.  
  2221. /*
  2222. * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
  2223. */
  2224. static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
  2225.                                      GLuint v1, GLuint v2, GLuint pv )
  2226. {
  2227.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2228. #define INTERP_Z 1
  2229. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2230. #define PIXEL_TYPE GLuint
  2231.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2232. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2233. #define SETUP_CODE                  \
  2234.     unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \
  2235.     VB->Color[pv][1], VB->Color[pv][2] );
  2236. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2237.     {                                   \
  2238.     GLint i, len = RIGHT-LEFT;                      \
  2239.     for (i=0;i<len;i++) {                       \
  2240.     GLdepth z = FixedToDepth(ffz);                  \
  2241.     if (z < zRow[i]) {                      \
  2242.     pRow[i] = p;                            \
  2243.     zRow[i] = z;                            \
  2244.     }                                   \
  2245.     ffz += fdzdx;                           \
  2246.     }                                   \
  2247.     }
  2248. #ifdef WIN32
  2249.     #include "..\tritemp.h"
  2250. #else
  2251.     #include "tritemp.h"
  2252. #endif
  2253. }
  2254.  
  2255.  
  2256. /*
  2257. * XImage, flat, depth-buffered, PF_8R8G8B triangle.
  2258. */
  2259. static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2260.                                    GLuint v2, GLuint pv )
  2261. {
  2262.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2263. #define INTERP_Z 1
  2264. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2265. #define PIXEL_TYPE GLuint
  2266.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2267. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2268. #define SETUP_CODE                  \
  2269.     unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \
  2270.     VB->Color[pv][1], VB->Color[pv][2] );
  2271. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2272.     {                           \
  2273.     GLint i, len = RIGHT-LEFT;              \
  2274.     for (i=0;i<len;i++) {               \
  2275.     GLdepth z = FixedToDepth(ffz);          \
  2276.     if (z < zRow[i]) {              \
  2277.     pRow[i] = p;                    \
  2278.     zRow[i] = z;                    \
  2279.     }                           \
  2280.     ffz += fdzdx;                   \
  2281.     }                           \
  2282.     }
  2283. #ifdef WIN32
  2284.     #include "..\tritemp.h"
  2285. #else
  2286.     #include "tritemp.h"
  2287. #endif
  2288. }
  2289.  
  2290.  
  2291. /*
  2292. * XImage, flat, depth-buffered, PF_5R6G5B triangle.
  2293. */
  2294. static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2295.                                    GLuint v2, GLuint pv )
  2296. {
  2297.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2298. #define INTERP_Z 1
  2299. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  2300. #define PIXEL_TYPE GLushort
  2301.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2302. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2303. #define SETUP_CODE                  \
  2304.     unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \
  2305.     VB->Color[pv][1], VB->Color[pv][2] );
  2306. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2307.     {                           \
  2308.     GLint i, len = RIGHT-LEFT;              \
  2309.     for (i=0;i<len;i++) {               \
  2310.     GLdepth z = FixedToDepth(ffz);          \
  2311.     if (z < zRow[i]) {              \
  2312.     pRow[i] = p;                    \
  2313.     zRow[i] = z;                    \
  2314.     }                           \
  2315.     ffz += fdzdx;                   \
  2316.     }                           \
  2317.     }
  2318. #ifdef WIN32
  2319.     #include "..\tritemp.h"
  2320. #else
  2321.     #include "tritemp.h"
  2322. #endif
  2323. }
  2324.  
  2325.  
  2326. /*
  2327. * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
  2328. */
  2329. static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2330.                                      GLuint v2, GLuint pv )
  2331. {
  2332.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2333. #define INTERP_RGB 1
  2334. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2335. #define PIXEL_TYPE GLuint
  2336.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2337. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2338. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2339.     {                                   \
  2340.     GLint xx;                               \
  2341.     PIXEL_TYPE *pixel = pRow;                       \
  2342.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
  2343.     *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),     \
  2344.                 FixedToInt(ffb) );          \
  2345.                 ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
  2346.     }                                   \
  2347.     }
  2348. #ifdef WIN32
  2349.     #include "..\tritemp.h"
  2350. #else
  2351.     #include "tritemp.h"
  2352. #endif
  2353. }
  2354.  
  2355.  
  2356. /*
  2357. * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
  2358. */
  2359. static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2360.                                    GLuint v2, GLuint pv )
  2361. {
  2362.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2363. #define INTERP_RGB 1
  2364. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2365. #define PIXEL_TYPE GLuint
  2366.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2367. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2368. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2369.     {                                   \
  2370.     GLint xx;                               \
  2371.     PIXEL_TYPE *pixel = pRow;                       \
  2372.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
  2373.     *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),     \
  2374.                 FixedToInt(ffb) );          \
  2375.                 ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
  2376.     }                                   \
  2377.     }
  2378. #ifdef WIN32
  2379.     #include "..\tritemp.h"
  2380. #else
  2381.     #include "tritemp.h"
  2382. #endif
  2383. }
  2384.  
  2385.  
  2386. /*
  2387. * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
  2388. */
  2389. static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2390.                                    GLuint v2, GLuint pv )
  2391. {
  2392.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2393. #define INTERP_RGB 1
  2394. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  2395. #define PIXEL_TYPE GLushort
  2396.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2397. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2398. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2399.     {                                   \
  2400.     GLint xx;                               \
  2401.     PIXEL_TYPE *pixel = pRow;                       \
  2402.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
  2403.     *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),     \
  2404.                 FixedToInt(ffb) );          \
  2405.                 ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
  2406.     }                                   \
  2407.     }
  2408. #ifdef WIN32
  2409.     #include "..\tritemp.h"
  2410. #else
  2411.     #include "tritemp.h"
  2412. #endif
  2413. }
  2414.  
  2415.  
  2416.  
  2417. /*
  2418. * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
  2419. */
  2420. static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
  2421.                                    GLuint v1, GLuint v2, GLuint pv )
  2422. {
  2423.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2424. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2425. #define PIXEL_TYPE GLuint
  2426.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2427. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2428. #define SETUP_CODE                  \
  2429.     unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \
  2430.     VB->Color[pv][1], VB->Color[pv][2] );
  2431. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2432.     {                           \
  2433.     GLint xx;                       \
  2434.     PIXEL_TYPE *pixel = pRow;               \
  2435.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
  2436.     *pixel = p;                 \
  2437.     }                           \
  2438.     }
  2439. #ifdef WIN32
  2440.     #include "..\tritemp.h"
  2441. #else
  2442.     #include "tritemp.h"
  2443. #endif
  2444. }
  2445.  
  2446.  
  2447. /*
  2448. * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
  2449. */
  2450. static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2451.                                  GLuint v2, GLuint pv )
  2452. {
  2453.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2454. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2455. #define PIXEL_TYPE GLuint
  2456.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2457. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2458. #define SETUP_CODE                  \
  2459.     unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \
  2460.     VB->Color[pv][1], VB->Color[pv][2] );
  2461. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2462.     {                           \
  2463.     GLint xx;                       \
  2464.     PIXEL_TYPE *pixel = pRow;               \
  2465.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
  2466.     *pixel = p;                 \
  2467.     }                           \
  2468.     }
  2469. #ifdef WIN32
  2470.     #include "..\tritemp.h"
  2471. #else
  2472.     #include "tritemp.h"
  2473. #endif
  2474. }
  2475.  
  2476.  
  2477. /*
  2478. * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
  2479. */
  2480. static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2481.                                  GLuint v2, GLuint pv )
  2482. {
  2483.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2484. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  2485. #define PIXEL_TYPE GLushort
  2486.     //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2487. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2488. #define SETUP_CODE                  \
  2489.     unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \
  2490.     VB->Color[pv][1], VB->Color[pv][2] );
  2491. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2492.     {                           \
  2493.     GLint xx;                       \
  2494.     PIXEL_TYPE *pixel = pRow;               \
  2495.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
  2496.     *pixel = p;                 \
  2497.     }                           \
  2498.     }
  2499. #ifdef WIN32
  2500.     #include "..\tritemp.h"
  2501. #else
  2502.     #include "tritemp.h"
  2503. #endif
  2504. }
  2505.  
  2506.  
  2507. /*
  2508. * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
  2509. */
  2510.  
  2511. static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2512.                                  GLuint v2, GLuint pv )
  2513. {
  2514.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2515. #define INTERP_Z 1
  2516. #define INTERP_INDEX 1
  2517. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2518. #define PIXEL_TYPE GLubyte
  2519. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2520. #define INNER_LOOP( LEFT, RIGHT, Y )                                \
  2521.     {                                                                   \
  2522.     GLint i, len = RIGHT-LEFT;                                      \
  2523.     for (i=0;i<len;i++) {                                           \
  2524.     GLdepth z = FixedToDepth(ffz);                              \
  2525.     if (z < zRow[i]) {                                          \
  2526.     pRow[i] = FixedToInt(ffi);                                  \
  2527.     zRow[i] = z;                                                \
  2528.     }                                                               \
  2529.     ffi += fdidx;                                                   \
  2530.     ffz += fdzdx;                                                   \
  2531.     }                                                               \
  2532.     }
  2533.  
  2534. #ifdef WIN32
  2535.     #include "..\tritemp.h"
  2536. #else
  2537.     #include "tritemp.h"
  2538. #endif
  2539. }
  2540.  
  2541.  
  2542. /*
  2543. * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
  2544. */
  2545.  
  2546. static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2547.                                GLuint v2, GLuint pv )
  2548. {
  2549.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2550. #define INTERP_Z 1
  2551. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2552. #define PIXEL_TYPE GLubyte
  2553. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2554. #define SETUP_CODE                                                  \
  2555.     GLuint index = VB->Index[pv];                                   \
  2556.     if (!VB->MonoColor) {                                           \
  2557.     /* set the color index */                                       \
  2558.     (*ctx->Driver.Index)( ctx, index );                         \
  2559.     }
  2560. #define INNER_LOOP( LEFT, RIGHT, Y )                                \
  2561.     {                                                                   \
  2562.     GLint i, len = RIGHT-LEFT;                                      \
  2563.     for (i=0;i<len;i++) {                                           \
  2564.     GLdepth z = FixedToDepth(ffz);                              \
  2565.     if (z < zRow[i]) {                                          \
  2566.     pRow[i] = index;                                            \
  2567.     zRow[i] = z;                                                \
  2568.     }                                                               \
  2569.     ffz += fdzdx;                                                   \
  2570.     }                                                               \
  2571.     }
  2572. #ifdef WIN32
  2573.     #include "..\tritemp.h"
  2574. #else
  2575.     #include "tritemp.h"
  2576. #endif
  2577. }
  2578.  
  2579.  
  2580.  
  2581. /*
  2582. * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
  2583. */
  2584.  
  2585. static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2586.                                GLuint v2, GLuint pv )
  2587. {
  2588.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2589. #define INTERP_Z 1
  2590. #define INTERP_INDEX 1
  2591. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2592. #define PIXEL_TYPE GLubyte
  2593. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2594. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2595.     {                                   \
  2596.     GLint xx;                               \
  2597.     PIXEL_TYPE *pixel = pRow;                       \
  2598.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
  2599.     *pixel = FixedToInt(ffi);           \
  2600.     ffi += fdidx;           \
  2601.     }                                   \
  2602.     }
  2603. #ifdef WIN32
  2604.     #include "..\tritemp.h"
  2605. #else
  2606.     #include "tritemp.h"
  2607. #endif
  2608. }
  2609.  
  2610.  
  2611. /*
  2612. * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
  2613. */
  2614. static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2615.                              GLuint v2, GLuint pv )
  2616. {
  2617.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2618. #define INTERP_Z 1
  2619. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2620. #define PIXEL_TYPE GLubyte
  2621. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2622. #define SETUP_CODE                                                  \
  2623.     GLuint index = VB->Index[pv];                                   \
  2624.     if (!VB->MonoColor) {                                           \
  2625.     /* set the color index */                                       \
  2626.     (*ctx->Driver.Index)( ctx, index );                         \
  2627.     }
  2628. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2629.     {                           \
  2630.     GLint xx;                       \
  2631.     PIXEL_TYPE *pixel = pRow;               \
  2632.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
  2633.     *pixel = index;                 \
  2634.     }                           \
  2635.     }
  2636. #ifdef WIN32
  2637.     #include "..\tritemp.h"
  2638. #else
  2639.     #include "tritemp.h"
  2640. #endif
  2641. }
  2642.  
  2643. /*
  2644. * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
  2645. */
  2646. static void smooth_DITHER8_z_triangle( GLcontext *ctx,
  2647.                                       GLuint v0, GLuint v1, GLuint v2,
  2648.                                       GLuint pv )
  2649. {
  2650.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2651.     DITHER_RGB_TO_8BIT_SETUP
  2652. #define INTERP_Z 1
  2653. #define INTERP_RGB 1
  2654. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2655. #define PIXEL_TYPE GLubyte
  2656. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2657. #define INNER_LOOP( LEFT, RIGHT, Y )                                    \
  2658.     {                                                                       \
  2659.     GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
  2660.     for (i=0;i<len;i++,xx++) {                                          \
  2661.     GLdepth z = FixedToDepth(ffz);                                  \
  2662.     if (z < zRow[i]) {                                              \
  2663.     DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg),           \
  2664.     FixedToInt(ffb), xx, yy);               \
  2665.     pRow[i] = pixelDithered;                                        \
  2666.     zRow[i] = z;                                                    \
  2667.     }                                                                   \
  2668.     ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
  2669.     ffz += fdzdx;                                                       \
  2670.     }                                                                   \
  2671.     }
  2672. #ifdef WIN32
  2673.     #include "..\tritemp.h"
  2674. #else
  2675.     #include "tritemp.h"
  2676. #endif
  2677. }
  2678.  
  2679. /*
  2680. * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
  2681. */
  2682. static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2683.                                     GLuint v2, GLuint pv )
  2684. {
  2685.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2686.     DITHER_RGB_TO_8BIT_SETUP
  2687. #define INTERP_Z 1
  2688. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2689. #define PIXEL_TYPE GLubyte
  2690. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2691.  
  2692. #define INNER_LOOP( LEFT, RIGHT, Y )                                    \
  2693.     {                                                                       \
  2694.     GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
  2695.     for (i=0;i<len;i++,xx++) {                                          \
  2696.     GLdepth z = FixedToDepth(ffz);                                  \
  2697.     if (z < zRow[i]) {                                              \
  2698.     DITHER_RGB_TO_8BIT( VB->Color[pv][0],                           \
  2699.              VB->Color[pv][1], VB->Color[pv][2], xx, yy);               \
  2700.              pRow[i] = pixelDithered;                                       \
  2701.              zRow[i] = z;                                                   \
  2702.     }                                                                   \
  2703.     ffz += fdzdx;                                                       \
  2704.     }                                                                   \
  2705.     }
  2706. #ifdef WIN32
  2707.     #include "..\tritemp.h"
  2708. #else
  2709.     #include "tritemp.h"
  2710. #endif
  2711. }
  2712.  
  2713. /*
  2714. * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
  2715. */
  2716. static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2717.                                     GLuint v2, GLuint pv )
  2718. {
  2719.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2720.     DITHER_RGB_TO_8BIT_SETUP
  2721. #define INTERP_RGB 1
  2722. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2723. #define PIXEL_TYPE GLubyte
  2724. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2725. #define INNER_LOOP( LEFT, RIGHT, Y )                                    \
  2726.     {                                                                       \
  2727.     GLint xx, yy = FLIP(Y);                                             \
  2728.     PIXEL_TYPE *pixel = pRow;                                           \
  2729.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
  2730.     DITHER_RGB_TO_8BIT( VB->Color[pv][0],   VB->Color[pv][1], VB->Color[pv][2], xx, yy);\
  2731.     *pixel = pixelDithered;                                         \
  2732.     ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
  2733.     }                                                                   \
  2734.     }
  2735. #ifdef WIN32
  2736.     #include "..\tritemp.h"
  2737. #else
  2738.     #include "tritemp.h"
  2739. #endif
  2740. }
  2741.  
  2742. /*
  2743. * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
  2744. */
  2745.  
  2746. static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2747.                                   GLuint v2, GLuint pv )
  2748. {
  2749.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2750.     DITHER_RGB_TO_8BIT_SETUP
  2751. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2752. #define PIXEL_TYPE GLubyte
  2753. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2754.  
  2755. #define INNER_LOOP( LEFT, RIGHT, Y )                                    \
  2756.     {                                                                       \
  2757.     GLint xx, yy = FLIP(Y);                                             \
  2758.     PIXEL_TYPE *pixel = pRow;                                           \
  2759.     for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
  2760.     DITHER_RGB_TO_8BIT( VB->Color[pv][0],                               \
  2761.              VB->Color[pv][1], VB->Color[pv][2], xx, yy);               \
  2762.              *pixel = pixelDithered;                                            \
  2763.     }                                                                   \
  2764.     }
  2765. #ifdef WIN32
  2766.     #include "..\tritemp.h"
  2767. #else
  2768.     #include "tritemp.h"
  2769. #endif
  2770. }
  2771.  
  2772.  
  2773.  
  2774.  
  2775. static triangle_func choose_triangle_function( GLcontext *ctx )
  2776. {
  2777.     WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2778.     int depth = wmesa->cColorBits;
  2779.  
  2780.     if (ctx->Polygon.SmoothFlag)     return NULL;
  2781.     if (ctx->Texture.Enabled)        return NULL;
  2782.     if (!wmesa->db_flag) return NULL;
  2783.     /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
  2784.     if (   ctx->Light.ShadeModel==GL_SMOOTH
  2785.         && ctx->RasterMask==DEPTH_BIT
  2786.         && ctx->Depth.Func==GL_LESS
  2787.         && ctx->Depth.Mask==GL_TRUE
  2788.         && ctx->Polygon.StippleFlag==GL_FALSE) {
  2789.         switch (wmesa->pixelformat) {
  2790.         case PF_8A8B8G8R:
  2791.             return smooth_8A8B8G8R_z_triangle;
  2792.         case PF_8R8G8B:
  2793.             return smooth_8R8G8B_z_triangle;
  2794.         case PF_5R6G5B:
  2795.             return smooth_5R6G5B_z_triangle;
  2796.         case PF_DITHER8:
  2797.             return  smooth_DITHER8_z_triangle;
  2798.         case PF_INDEX8:
  2799.             return smooth_ci_z_triangle;
  2800.         default:
  2801.             return NULL;
  2802.         }
  2803.     }
  2804.     if (   ctx->Light.ShadeModel==GL_FLAT
  2805.         && ctx->RasterMask==DEPTH_BIT
  2806.         && ctx->Depth.Func==GL_LESS
  2807.         && ctx->Depth.Mask==GL_TRUE
  2808.         && ctx->Polygon.StippleFlag==GL_FALSE) {
  2809.         switch (wmesa->pixelformat) {
  2810.         case PF_8A8B8G8R:
  2811.             return flat_8A8B8G8R_z_triangle;
  2812.         case PF_8R8G8B:
  2813.             return flat_8R8G8B_z_triangle;
  2814.         case PF_5R6G5B:
  2815.             return flat_5R6G5B_z_triangle;
  2816.         case PF_DITHER8:
  2817.             return flat_DITHER8_z_triangle;
  2818.         case PF_INDEX8:
  2819.             return flat_ci_z_triangle;
  2820.         default:
  2821.             return NULL;
  2822.         }
  2823.     }
  2824.     if (   ctx->RasterMask==0   /* no depth test */
  2825.         && ctx->Light.ShadeModel==GL_SMOOTH
  2826.         && ctx->Polygon.StippleFlag==GL_FALSE) {
  2827.         switch (wmesa->pixelformat) {
  2828.         case PF_8A8B8G8R:
  2829.             return smooth_8A8B8G8R_triangle;
  2830.         case PF_8R8G8B:
  2831.             return smooth_8R8G8B_triangle;
  2832.         case PF_5R6G5B:
  2833.             return smooth_5R6G5B_triangle;
  2834.         case PF_DITHER8:
  2835.             return smooth_DITHER8_triangle;
  2836.         case PF_INDEX8:
  2837.             return smooth_ci_triangle;
  2838.         default:
  2839.             return NULL;
  2840.         }
  2841.     }
  2842.  
  2843.     if (   ctx->RasterMask==0   /* no depth test */
  2844.         && ctx->Light.ShadeModel==GL_FLAT
  2845.         && ctx->Polygon.StippleFlag==GL_FALSE) {
  2846.         switch (wmesa->pixelformat) {
  2847.         case PF_8A8B8G8R:
  2848.             return flat_8A8B8G8R_triangle;
  2849.         case PF_8R8G8B:
  2850.             return flat_8R8G8B_triangle;
  2851.         case PF_5R6G5B:
  2852.             return flat_5R6G5B_triangle;
  2853.         case PF_DITHER8:
  2854.             return flat_DITHER8_triangle;
  2855.         case PF_INDEX8:
  2856.             return flat_ci_triangle;
  2857.         default:
  2858.             return NULL;
  2859.         }
  2860.     }
  2861.  
  2862.     return NULL;
  2863.     }
  2864. }
  2865.  
  2866. /*
  2867. * Define a new viewport and reallocate auxillary buffers if the size of
  2868. * the window (color buffer) has changed.
  2869. */
  2870. void WMesaViewport( GLcontext *ctx,
  2871.                    GLint x, GLint y, GLsizei width, GLsizei height )
  2872. {
  2873.     /* Save viewport */
  2874.     ctx->Viewport.X = x;
  2875.     ctx->Viewport.Width = width;
  2876.     ctx->Viewport.Y = y;
  2877.     ctx->Viewport.Height = height;
  2878.  
  2879.     /* compute scale and bias values */
  2880.     ctx->Viewport.Sx = (GLfloat) width / 2.0F;
  2881.     ctx->Viewport.Tx = ctx->Viewport.Sx + x;
  2882.     ctx->Viewport.Sy = (GLfloat) height / 2.0F;
  2883.     ctx->Viewport.Ty = ctx->Viewport.Sy + y;
  2884. }
  2885.